use async_trait::async_trait;
use futures::Future;
use russh::server::{Auth, Session};
use russh::*;
use russh_keys::*;
use std::io::{stdin, Read};
use std::sync::Arc;
use std::thread;

struct Client {}

#[async_trait]
impl client::Handler for Client {
    type Error = anyhow::Error;

    async fn check_server_key(
        self,
        server_public_key: &key::PublicKey,
    ) -> Result<(Self, bool), Self::Error> {
        println!("check_server_key: {:?}", server_public_key);
        Ok((self, true))
    }

    async fn data(
        self,
        channel: ChannelId,
        data: &[u8],
        session: client::Session,
    ) -> Result<(Self, client::Session), Self::Error> {
        println!(
            "data on channel {:?}: {:?}",
            channel,
            std::str::from_utf8(data)
        );
        Ok((self, session))
    }
}

pub async fn start() {
    let config = russh::client::Config::default();
    let config = Arc::new(config);
    let sh = Client {};

    let mut session = russh::client::connect(config, ("192.168.1.157", 22), sh)
        .await
        .unwrap();
    if session
        .authenticate_password("isms", "itc123")
        .await
        .unwrap()
    {
        let mut channel = session.channel_open_session().await.unwrap();
        channel.request_shell(true).await.unwrap();
        let mode: (Pty, u32) = (Pty::VEOF, 1);
        let terminal_modes: [(Pty, u32); 1] = [mode];
        channel
            .request_pty(true, "xterm", 100, 100, 100, 100, &terminal_modes)
            .await
            .unwrap();

            
        let data1 = "touch test.1";
        channel.data(data1.as_bytes()).await.unwrap();
        

        // let th1 = tokio::spawn(async move {
        //     loop {
        //         let mut buf = [0; 1024];
        //         match stdin().read(&mut buf) {
        //             Ok(c) => {
        //                 if c > 0 {
        //                     let s = std::str::from_utf8(&buf[..c]).unwrap();
        //                     println!("send data = {}", s);
        //                     channel.data(s.as_bytes()).await.unwrap();
        //                 }
        //             }
        //             Err(err) => {
        //                 println!("error: {:?}", err);
        //             }
        //         }
        //     }
        // });

        // if let Some(msg) = channel.wait().await {
        //     println!("{:?}", msg)
        // }

        // th1.await;
    }
}
